package com.zenithmind.document.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.document.pojo.domain.Document;
import com.zenithmind.document.pojo.query.DocumentQueryDTO;
import com.zenithmind.document.pojo.vo.DocumentDetailVO;
import com.zenithmind.document.pojo.vo.DocumentStatisticsVO;
import com.zenithmind.document.pojo.vo.DocumentVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface DocumentMapper extends BaseMapper<Document> {

    /**
     * 分页查询文档（包含关联信息）
     * 
     * @param page 分页参数
     * @param queryDTO 查询条件
     * @param userId 用户ID
     * @return 分页结果
     */
    IPage<DocumentVO> selectDocumentPageWithDetails(Page<DocumentVO> page, 
                                                   @Param("query") DocumentQueryDTO queryDTO, 
                                                   @Param("userId") String userId);

    /**
     * 获取文档详情（包含关联信息）
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @return 文档详情
     */
    DocumentDetailVO selectDocumentDetailWithUser(@Param("documentId") String documentId, 
                                                  @Param("userId") String userId);

    /**
     * 搜索文档
     * 
     * @param keyword 关键词
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> searchDocuments(@Param("keyword") String keyword, 
                                    @Param("userId") String userId, 
                                    @Param("limit") Integer limit);

    /**
     * 全文搜索文档
     * 
     * @param searchText 搜索文本
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> fullTextSearchDocuments(@Param("searchText") String searchText, 
                                           @Param("userId") String userId, 
                                           @Param("limit") Integer limit);

    /**
     * 获取用户文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectUserDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 获取分类文档
     * 
     * @param categoryId 分类ID
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectCategoryDocuments(@Param("categoryId") String categoryId, 
                                           @Param("userId") String userId, 
                                           @Param("limit") Integer limit);

    /**
     * 获取热门文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    @Select("SELECT d.*, u.real_name as creator_name, dc.name as category_name " +
            "FROM document d " +
            "LEFT JOIN user u ON d.creator_id = u.id " +
            "LEFT JOIN document_category dc ON d.category_id = dc.id " +
            "WHERE d.status = 1 AND d.deleted = 0 " +
            "AND (d.access_level = 1 OR d.creator_id = #{userId}) " +
            "ORDER BY d.view_count DESC, d.download_count DESC " +
            "LIMIT #{limit}")
    List<DocumentVO> selectHotDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 获取最新文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    @Select("SELECT d.*, u.real_name as creator_name, dc.name as category_name " +
            "FROM document d " +
            "LEFT JOIN user u ON d.creator_id = u.id " +
            "LEFT JOIN document_category dc ON d.category_id = dc.id " +
            "WHERE d.status = 1 AND d.deleted = 0 " +
            "AND (d.access_level = 1 OR d.creator_id = #{userId}) " +
            "ORDER BY d.create_time DESC " +
            "LIMIT #{limit}")
    List<DocumentVO> selectLatestDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 获取推荐文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectRecommendedDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 获取相关文档
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectRelatedDocuments(@Param("documentId") String documentId, 
                                          @Param("userId") String userId, 
                                          @Param("limit") Integer limit);

    /**
     * 获取收藏文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectFavoriteDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 获取最近访问文档
     * 
     * @param userId 用户ID
     * @param limit 限制数量
     * @return 文档列表
     */
    List<DocumentVO> selectRecentDocuments(@Param("userId") String userId, @Param("limit") Integer limit);

    /**
     * 检查文档权限
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @param permission 权限类型
     * @return 是否有权限
     */
    Boolean checkDocumentPermission(@Param("documentId") String documentId, 
                                   @Param("userId") String userId, 
                                   @Param("permission") String permission);

    /**
     * 更新文档统计
     * 
     * @param documentId 文档ID
     * @param type 统计类型（view, download, favorite）
     * @return 影响行数
     */
    @Update("UPDATE document SET " +
            "view_count = CASE WHEN #{type} = 'view' THEN view_count + 1 ELSE view_count END, " +
            "download_count = CASE WHEN #{type} = 'download' THEN download_count + 1 ELSE download_count END, " +
            "favorite_count = CASE WHEN #{type} = 'favorite' THEN favorite_count + 1 ELSE favorite_count END, " +
            "last_access_time = CASE WHEN #{type} IN ('view', 'download') THEN NOW() ELSE last_access_time END, " +
            "update_time = NOW() " +
            "WHERE id = #{documentId}")
    int updateDocumentStatistics(@Param("documentId") String documentId, @Param("type") String type);

    /**
     * 获取文档统计信息
     * 
     * @param documentId 文档ID
     * @return 统计信息
     */
    DocumentStatisticsVO selectDocumentStatistics(@Param("documentId") String documentId);

    /**
     * 批量更新文档状态
     * 
     * @param documentIds 文档ID列表
     * @param status 状态
     * @return 影响行数
     */
    int batchUpdateDocumentStatus(@Param("documentIds") List<String> documentIds, @Param("status") Integer status);

    /**
     * 批量移动文档
     * 
     * @param documentIds 文档ID列表
     * @param categoryId 目标分类ID
     * @return 影响行数
     */
    @Update("<script>" +
            "UPDATE document SET category_id = #{categoryId}, update_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='documentIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchMoveDocuments(@Param("documentIds") List<String> documentIds, @Param("categoryId") String categoryId);

    /**
     * 复制文档
     * 
     * @param sourceDocumentId 源文档ID
     * @param newName 新文档名称
     * @param userId 用户ID
     * @return 新文档ID
     */
    String copyDocument(@Param("sourceDocumentId") String sourceDocumentId, 
                       @Param("newName") String newName, 
                       @Param("userId") String userId);

    /**
     * 获取文档版本列表
     * 
     * @param documentId 文档ID
     * @return 版本列表
     */
    List<DocumentVO> selectDocumentVersions(@Param("documentId") String documentId);

    /**
     * 创建文档版本
     * 
     * @param documentId 文档ID
     * @param versionNumber 版本号
     * @param description 版本描述
     * @param userId 用户ID
     * @return 版本ID
     */
    String createDocumentVersion(@Param("documentId") String documentId, 
                                @Param("versionNumber") String versionNumber, 
                                @Param("description") String description, 
                                @Param("userId") String userId);

    /**
     * 恢复文档版本
     * 
     * @param documentId 文档ID
     * @param versionId 版本ID
     * @param userId 用户ID
     * @return 影响行数
     */
    int restoreDocumentVersion(@Param("documentId") String documentId, 
                              @Param("versionId") String versionId, 
                              @Param("userId") String userId);

    /**
     * 收藏文档
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @return 影响行数
     */
    int favoriteDocument(@Param("documentId") String documentId, @Param("userId") String userId);

    /**
     * 取消收藏文档
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @return 影响行数
     */
    @Update("UPDATE document_favorite SET deleted = 1, update_time = NOW() " +
            "WHERE document_id = #{documentId} AND user_id = #{userId}")
    int unfavoriteDocument(@Param("documentId") String documentId, @Param("userId") String userId);

    /**
     * 检查用户是否收藏了文档
     * 
     * @param userId 用户ID
     * @param documentId 文档ID
     * @return 是否收藏
     */
    @Select("SELECT COUNT(*) > 0 FROM document_favorite " +
            "WHERE user_id = #{userId} AND document_id = #{documentId} AND deleted = 0")
    Boolean checkUserFavoriteDocument(@Param("userId") String userId, @Param("documentId") String documentId);

    /**
     * 记录文档访问
     * 
     * @param documentId 文档ID
     * @param userId 用户ID
     * @param accessType 访问类型
     * @param deviceType 设备类型
     * @param ipAddress IP地址
     * @return 影响行数
     */
    int recordDocumentAccess(@Param("documentId") String documentId, 
                           @Param("userId") String userId, 
                           @Param("accessType") String accessType, 
                           @Param("deviceType") String deviceType, 
                           @Param("ipAddress") String ipAddress);

    /**
     * 清理过期文档
     * 
     * @param expireTime 过期时间
     * @return 清理数量
     */
    @Update("UPDATE document SET status = 2, update_time = NOW() " +
            "WHERE expire_time IS NOT NULL AND expire_time < #{expireTime} AND status = 1")
    int cleanupExpiredDocuments(@Param("expireTime") LocalDateTime expireTime);

    /**
     * 获取文档存储统计
     * 
     * @param userId 用户ID
     * @return 存储统计
     */
    DocumentStatisticsVO selectDocumentStorageStatistics(@Param("userId") String userId);
}
